using Basis;
using NL.UI;
using UnityEngine;

namespace NL.Advanced
{
    public static class GameObjectExtension
    {
        public static T GETOrAddComponent<T>(this GameObject go, bool forceadd = false) where T : Component
        {
            if (go == null) return null;
            T comp = go.GetComponent<T>();

            if (comp != null && forceadd)
            {
                GameObject.Destroy(comp);
                comp = null;
            }

            if (comp == null)
                comp = go.AddComponent<T>();
            return comp;
        }

        public static T GETOrAddComponent<T>(this Component go, bool forceadd = false) where T : Component
        {
            if (go == null) return null;
            T comp = go.GetComponent<T>();

            if (comp != null && forceadd)
            {
                GameObject.Destroy(comp); comp = null;
            }
            if (comp == null)
                comp = go.gameObject.AddComponent<T>();

            return comp;
        }

        public static void CLEARChildren(this GameObject go)
        {
            var trans = go.transform;
            trans.CLEARChildren();
        }

        public static void CLEARChildren(this Transform trans)
        {
            while (trans.childCount > 0)
            {
                var child = trans.GetChild(0);
                child.parent = null;
                GameObject.Destroy(child.gameObject);
            }
        }

        /// <summary>
        /// 设置对象自身及所有子节点的层级
        /// </summary>
        /// <param name="who"></param>
        /// <param name="layer"></param>
        public static void SETLayer(this GameObject who, int layer)
        {
            who.transform.SETLayer(layer);
        }

        public static GameObject GETChildByName(this GameObject who, string childName)
        {
            if (!string.IsNullOrEmpty(childName))
            {
                int childCount = who.transform.childCount;
                for (int i = 0; i < childCount; i++)
                {
                    var childTsf = who.transform.GetChild(i);
                    if (childTsf != null && childTsf.gameObject.name == childName)
                    {
                        return childTsf.gameObject;
                    }
                }
            }

            return null;
        }

        /// <summary>
        /// 设置对象自身及所有子节点的层级
        /// </summary>
        /// <param name="who"></param>
        /// <param name="layer"></param>
        public static void SETLayer(this Transform who, int layer)
        {
            who.gameObject.layer = layer;
            int index = 0;
            while (index < who.childCount)
            {
                //who.GetChild(index++).SETLayer(layer);
                who.GetChild(index).SETLayer(layer);
                index++;
            }
        }

        /// <summary>
        /// 触发控件子节点数据绑定
        /// </summary>
        /// <param name="who"></param>
        public static void DispatchUIInfoChanged(this GameObject who)
        {
            UIInfo[] componentsInChildren = who.GetComponentsInChildren<UIInfo>(includeInactive: true);
            if (componentsInChildren != null)
            {
                foreach (UIInfo uiinfo in componentsInChildren)
                {
                    if (uiinfo.gameObject != who)
                    {
                        uiinfo.Reset(null);
                    }
                }
            }
        }

        public static Rigidbody RIGINormalize(this GameObject who)
        {
            var _Rigi = GETOrAddComponent<Rigidbody>(who);

            if (_Rigi != null)
            {
                _Rigi.collisionDetectionMode = CollisionDetectionMode.Continuous;
                _Rigi.useGravity = false;
                _Rigi.isKinematic = true;
                _Rigi.constraints = RigidbodyConstraints.FreezeAll;
            }
            return _Rigi;
        }

        public static void COLORPaintWithMaterial(this GameObject who, Color color)
        {
            if (who == null) return;

            SkinnedMeshRenderer[] all = who.GetComponentsInChildren<SkinnedMeshRenderer>();

            if (all == null) return;

            foreach (var a in all)
            {
                //a.material.SetFloat("_EnableMinorColor", 1);
                a.material.SetColor("_MinorColor", color);
            }
        }



        public static void COLORPaintWhithCamp(this GameObject who)
        {
            if (who == null) return;

            var campowner = who.GetComponentInParent<ICampOwner>();
            if (campowner != null)
            {
                var Camp = campowner.Camp;

                Color color = Camp.TOColor();

                COLORPaintWithMaterial(who, color);
            }
        }

        public static void COLORPaintForUGCWithCamp(this GameObject who)
        {
            if (who == null) return;

            var campowner = who.GetComponentInParent<ICampOwner>();
            if (campowner != null)
            {
                var Camp = campowner.Camp;

                Color color = Camp.TOColor();

                COLORPaintForUGC(who, color);
            }
        }

        public static void COLORPaintForUGC(this GameObject who, Color color)
        {
            if (who == null) return;

            MeshRenderer[] all = who.GetComponentsInChildren<MeshRenderer>();

            if (all == null) return;

            foreach (var a in all)
            {
                //a.material.SetFloat("_EnableMinorColor", 1);
                a.material.SetColor("_MinorColor", color);
            }
        }
        public static void SHADOWOpen(this GameObject who, bool open)
        {

            var all = who.GetComponentsInChildren<SkinnedMeshRenderer>();
            if (all != null)
            {
                foreach (var a in all)
                {
                    a.shadowCastingMode = open ? UnityEngine.Rendering.ShadowCastingMode.On : UnityEngine.Rendering.ShadowCastingMode.Off;
                }
            }

        }

    }
    public static class TransformExtension
    {
        public static void SETPositoionXZ(this Transform who, Vector3 pos, Space space = Space.World)
        {
            float y = who.position.y;
            who.position = new Vector3(pos.x, y, pos.z);
        }

        public static void SETPositoionXZ(this Transform who, Vector3 pos, float y, Space space = Space.World)
        {
            who.position = new Vector3(pos.x, y, pos.z);
        }

        public static void SETPositoionY(this Transform who, float y, Space space = Space.World)
        {
            if (space == Space.World)
                who.position = new Vector3(who.position.x, y, who.position.z);
            else
                who.localPosition = new Vector3(who.position.x, y, who.position.z);
        }

        public static float RADIUSDistance(this Transform who, Transform other)
        {
            Vector3 A = who.transform.position;
            Vector3 B = other.transform.position;
            B.y = A.y;

            float dist = Vector3.Distance(A, B);

            var radius = who.GetComponent<IRadius>();
            if (radius != null)
                dist -= radius.Radius;

            radius = other.GetComponent<IRadius>();
            if (radius != null)
                dist -= radius.Radius;

            return dist;
        }
    }
}